import time
import random
import json

class FCB:
    def __init__(self):
        self.name=[]
        self.year=0;self.month=0;self.day=0;self.hour=0;self.minute=0;self.second=0
        self.length=0
        self.startaddr=0
        self.node=0
fcb=[FCB() for i in range(1000)]

class Directory:
    def __init__(self):
        self.name =[['0' for col in range(100)]for row in range(100)]
        self.year=0 ;self.month=0;self.day=0;self.hour=0;self.minute=0
        self.judge=[0 for i in range(100)]
        self.link=[0 for i in range(100)]
        self.node=0
        self.num=0
Dir=[Directory()for i in range(1000)]


class imshow:
    def __init__(self):
        self.child=[{"children":[],"date":"","name":"","size":0} for i in range(100)]
        self.clink=[0 for i in range(100)]
d=[imshow()for i in range(1000)]

path = 1; Time = 1; used_fcb = 0; used_dir = 1
step = 0;                                                       #存储路径深度
steps=[['0' for col in range(100)]for row in range(100)];       #存储路径
FAT=[0 for i in range(256)];                                                         #Fat表
bitmap=[ 0 for i in range(32)]                                                 #位示图
pts1=[0 for i in range(100)]
pt1=0;
pts1[pt1]="C:\\"
result={}

class PM:
    def __init__(self,MC):
        self.MC=MC
    def _mk(self,path, size=0):
        global Dir
        pl = path.split("\\")
        print(pl)
        m = 0
        for i in range(1, len(pl) - 1):
            count = 0
            for j in range(Dir[i - 1].num):
                if Dir[i - 1].name[j] == pl[i]:
                    count = 1
            if count == 0:
                md(pl[i])
            cd(pl[i])
            m = i
        if size == 0:
            md(pl[m + 1])
        else:
            if  self.MC.write_file(pl[m + 1], size):
                mk(pl[m + 1], size)
                for i in range(1, len(pl)):
                    cd('..')
                return True
            else:
                for i in range(1, len(pl)):
                    cd('..')
                return False

    def _del(self,p, jud):
        global Dir
        pl = p.split("\\")
        for i in range(1, len(pl) - 1):
            count = 0
            for j in range(Dir[i - 1].num):
                if Dir[i - 1].name[j] == pl[i]:
                    cd(pl[i])
                    count = 1
            if count == 0:
                return print("要删除的文件或文件夹不存在")
        if jud == 0:
            rd(pl[i + 1])
        else:
            self.MC.delete_file(pl[i + 1])
            rk(pl[i + 1])

    def _Search(self,op, p):
        global Dir, fcb, pts1, pt1, all2
        for i in range(2, Dir[p - 1].num):
            way = ""
            if not Dir[p - 1].judge[i]:
                pt1 += 1
                pts1[pt1] = Dir[p - 1].name[i] + "\\"
                _Search(op, Dir[p - 1].link[i])
                pt1 -= 1
            else:
                pt1 += 1
                if op == fcb[Dir[p - 1].link[i]].name:
                    pts1[pt1] = fcb[Dir[p - 1].link[i]].name
                    for j in range(pt1 + 1):
                        way += pts1[j]
                    result[way] = fcb[Dir[p - 1].link[i]].length
                    pt1 -= 1

class SC:
    def __init__(self):
        d[0].child[0]["name"] = "C:"
        d[0].clink[0] = 1
    def pac(self,p=1):
        global Dir, fcb, d
        for i in range(2, Dir[p - 1].num):
            if not Dir[p - 1].judge[i]:
                d[p].child[i - 2]["date"] = "{}-{}-{} {}:{}:{}".format(Dir[Dir[p - 1].link[i] - 1].year,
                                                                       Dir[Dir[p - 1].link[i] - 1].month,
                                                                       Dir[Dir[p - 1].link[i] - 1].day,
                                                                       Dir[Dir[p - 1].link[i] - 1].hour,
                                                                       Dir[Dir[p - 1].link[i] - 1].minute,
                                                                       Dir[Dir[p - 1].link[i] - 1].second)
            else:
                d[p].child[i - 2]["date"] = "{}-{}-{} {}:{}:{}".format(fcb[Dir[p - 1].link[i]].year,
                                                                       fcb[Dir[p - 1].link[i]].month,
                                                                       fcb[Dir[p - 1].link[i]].day,
                                                                       fcb[Dir[p - 1].link[i]].hour,
                                                                       fcb[Dir[p - 1].link[i]].minute,
                                                                       fcb[Dir[p - 1].link[i]].second)
            d[p].child[i - 2]["name"] = Dir[p - 1].name[i]
            if Dir[p - 1].judge[i]:
                d[p].child[i - 2]["size"] = fcb[Dir[p - 1].link[i]].length
            if not Dir[p - 1].judge[i]:
                d[p].clink[i - 2] = Dir[p - 1].link[i]
            self.pac(p + 1)

    def exhibit(self,p=1):
        global d, Dir
        M = []
        for i in range(Dir[p - 1].num - 2):
            if not Dir[p - 1].judge[i + 2] and Dir[Dir[p - 1].link[i + 2] - 1].num - 2 > 0:
                rt = self.exhibit(Dir[p - 1].link[i + 2])
                d[p].child[i]["children"] = rt
                M.append(d[p].child[i])
            else:
                M.append(d[p].child[i])
        return M

    def tojson(self,p):
        global d
        d[0].child[0]["children"] = p
        return d[0].child[0]

def init(n,root):           #初始化结点信息
    global Dir,Time
    Dir[n].name[0]="."
    Dir[n].name[1]=".."
    Dir[n].judge[0]=Dir[n].judge[1]=0
    Dir[n].link[0] = Time
    Dir[n].link[1] = root
    Time+=1
    Dir[n].node = Time
    Dir[n].num = 2
    T=time.localtime()
    Dir[n].year=T.tm_year
    Dir[n].month=T.tm_mon
    Dir[n].day=T.tm_mday
    Dir[n].hour=T.tm_hour
    Dir[n].minute=T.tm_min
    Dir[n].second=T.tm_sec

def init_bit_map():             #位示图初始化
    global bitmap
    for i in range(32):
        bitmap[i]=random.randint(0,99)%256
    for i in range(256):
        FAT[i]=-1

def get_bit_map(n):             #获取位示图
    return bool(bitmap[n // 8] & (1 << (7 - n % 8)))

def set_bit_map(n,k):           #修改位示图
    if k:
        bitmap[n // 8] = bitmap[n // 8] | (1 << (7 - n % 8));
    else:
        bitmap[n // 8] = bitmap[n // 8] & ~(1 << (7 - n % 8));

def show_bit_map():         #显示位示图
    global bitmap
    print("位示图")
    for i in range(16):
        for j in range(16):
            print("%d "%(bool(bitmap[(i * 16 + j) // 8] & (1 << (7 - (i * 16 + j) % 8)))),end="")
        print("")

def output_path():              #输出文件路径
    global step
    print("")
    print(r"    C:\\",end="")
    for i in range(step+1):
        if i==step:
            break
        elif i==0:
            print(steps[i],end="")
        else:
            print(r"\\%s"%steps[i])

def fat():                  #文件分配表
    global Dir,fcb,FAT
    for i in range(2,Dir[path-1].num):
        if Dir[path-1].judge[i]:
            print("{}:".format( Dir[path - 1].name[i]))
            k = fcb[Dir[path - 1].link[i]].startaddr
            for j in range(fcb[Dir[path - 1].link[i]].length):
                print("{} ".format(k),end="")
                k=FAT[k]
            print("")

def mk(opname,leng):                       #创建文件
    global Dir,fcb,used_fcb,Time
    fcb[used_fcb].name=opname             #文件名字
    fcb[used_fcb].length=leng           #文件大小
    for i in range(2,Dir[path-1].num):
        if Dir[path-1].judge[i] and Dir[path - 1].name[i]==fcb[used_fcb].name:          #在同级目录下查找是否有同名文件，若有则发送创建失败的消息；
            fcb[used_fcb].length+=leng
            print("文件复写成功")
            return
    j=0
    for i in range(256):
        if j<fcb[used_fcb].length:
            if not get_bit_map(i):
                j+=1
        else:
            break
    k=-1
    j=0
    for i in range(fcb[used_fcb].length):
        while get_bit_map(j):                               #查看磁盘是否有空闲的空间，若有，则将对应的空间修改为1
            j+=1
        set_bit_map(j,1)
        if k==-1:
            fcb[used_fcb].startaddr = j                     #修改文件配置表，记录文件的起始地址
        else:
            FAT[k] = j;
        k=j
        j+=1
    Dir[path - 1].name[Dir[path - 1].num]=fcb[used_fcb].name
    Time+=1
    fcb[used_fcb].node = Time
    Dir[path - 1].link[Dir[path - 1].num] = used_fcb
    Dir[path - 1].judge[Dir[path - 1].num] = 1
    t = time.localtime()
    fcb[used_fcb].year=t.tm_year
    fcb[used_fcb].month=t.tm_mon
    fcb[used_fcb].day=t.tm_mday
    fcb[used_fcb].hour=t.tm_hour
    fcb[used_fcb].minute=t.tm_min
    fcb[used_fcb].second=t.tm_sec
    Dir[path-1].num+=1
    used_fcb+=1

def dir():
    global Dir,fcb,Memory
    dir=0;file=0;sum=0
    show_bit_map()
    output_path()
    print("的目录")
    print("")
    print("")
    for i in range(Dir[path-1].num):
        if not Dir[path-1].judge[i]:
            print("{0}-{1}-{2}\t{3}:{4}:{5}\t".format(Dir[Dir[path - 1].link[i] - 1].year,Dir[Dir[path - 1].link[i] - 1].month,Dir[Dir[path - 1].link[i] - 1].day,Dir[Dir[path - 1].link[i] - 1].hour,Dir[Dir[path - 1].link[i] - 1].minute,Dir[Dir[path - 1].link[i] - 1].second))
            print("<DIR>\t{}".format(Dir[path-1].name[i]))
            dir+=1
        else:
            print("{0}-{1}-{2}\t{3}:{4}:{5}\t\t".format(fcb[Dir[path - 1].link[i]].year,fcb[Dir[path - 1].link[i]].month,fcb[Dir[path - 1].link[i]].day,fcb[Dir[path - 1].link[i]].hour,fcb[Dir[path - 1].link[i]].minute,fcb[Dir[path - 1].link[i]].second))
            print("{1}\t{0}".format(fcb[Dir[path - 1].link[i]].length,Dir[path - 1].name[i]))
            sum += fcb[Dir[path - 1].link[i]].length
            file+=1
    print( "\t\t{0}个文件\t{1}\t字节".format(file,sum))
    print("\t\t{0}个目录\t{1}\t可用字节".format(dir,Memory))
    fat()

output=[0 for i in range(100)]
def tree(p,deep):
    global Dir,output
    for i in range(2,Dir[p-1].num):
        for j in range(deep):
            if output[j]==True:
                print("|\t",end="")
            else:
                print("\t",end="")
        if i< Dir[p - 1].num - 1:
            print("├───{}".format(Dir[p - 1].name[i]))
        else:
            print("└───{}".format(Dir[p - 1].name[i]))
        output[deep]=False
        if i < Dir[p - 1].num - 1:
            output[deep] = True
        if not Dir[p - 1].judge[i]:
            tree(Dir[p - 1].link[i], deep + 1)

def cd(op):
    global path,step
    if op =="\\":
        path=1
        step=0
        return
    for i in range(Dir[path-1].num):
        if (not Dir[path - 1].judge[i]) and (Dir[path - 1].name[i]==op):
            path = Dir[path - 1].link[i]
            if i==1 and step:
                step-=1
            elif i!=1 and i:
                steps[step]=op
                step+=1
            return
    print("不存在该文件夹")

def md(op):                                               #创建文件夹
    global path,used_dir,Time
    for i in range(2,Dir[path-1].num):
        if (not Dir[path - 1].judge[i]) and Dir[path-1].name==op:
            print("文件已存在")
            return False
    init(used_dir,path)
    used_dir+=1
    Dir[path - 1].judge[Dir[path - 1].num] = 0          #类型为文件夹
    Dir[path - 1].link[Dir[path - 1].num] = used_dir
    Dir[path - 1].name[Dir[path - 1].num]=op
    Dir[path - 1].num+=1
    return True

def rd(op):
    global Dir,path
    for i in range(2,Dir[path-1].num):
        if (not Dir[path-1].judge[i])and Dir[path-1].name[i]==op:
            if Dir[Dir[path - 1].link[i] - 1].num  >2:
                print("该文件夹不为空, 不能删除")
            else:
                for j in range(i,Dir[path-1].num-1):
                    Dir[path - 1].link[j] = Dir[path - 1].link[j + 1]
                    Dir[path - 1].judge[j] = Dir[path - 1].judge[j + 1]
                    Dir[path - 1].name[j]= Dir[path - 1].name[j + 1]
                Dir[path-1].num-=1
                print("删除成功")
            return
    print("该文件夹不存在")

def rk(na):                                    #删除文件
    global Dir,path,FAT
    for i in range(2,Dir[path-1].num):
        if Dir[path-1].judge[i] and Dir[path - 1].name[i]== na:
            k = fcb[Dir[path - 1].link[i]].startaddr
            for i in range(fcb[Dir[path - 1].link[i]].length):
                set_bit_map(k, 0)
                k = FAT[k]
            for j in range(i,Dir[path - 1].num - 1):
                Dir[path - 1].link[j] = Dir[path - 1].link[j + 1]
                Dir[path - 1].judge[j] = Dir[path - 1].judge[j + 1]
                Dir[path - 1].name[j]=Dir[path - 1].name[j + 1]
            Dir[path - 1].num-=1
            print("删除成功")
            return
    print("没找到文件")

def _dir(choose):                               #模糊查询,支持*，？查询
    global Dir,path
    choose=choose+"\0"
    for i in range(Dir[path - 1].num):
        Dir[path - 1].name[i]=Dir[path - 1].name[i]+"\0"
        k=0
        k1=len(Dir[path - 1].name[i])
        for j in range(len(Dir[path - 1].name[i])):
            c1 = choose[k];
            c2 = Dir[path - 1].name[i][j]
            if choose[k]=='*':
                k+=1
            if choose[k] != '*' and choose[k] != '?' and choose[k] == Dir[path - 1].name[i][j]:
                k+=1
            elif choose[k]=='?':
                k+=1
        if k>=len(choose):
            if not Dir[path - 1].judge[i]:
                print("{}-{}-{}\t{}:{}:{}\t".format(Dir[Dir[path - 1].link[i] - 1].year,Dir[Dir[path - 1].link[i] - 1].month,Dir[Dir[path - 1].link[i] - 1].day,Dir[Dir[path - 1].link[i] - 1].hour,Dir[Dir[path - 1].link[i] - 1].minute,Dir[Dir[path - 1].link[i] - 1].second),end="")
                print("\t<DIR>\t",end="")
                print("{}".format(Dir[path - 1].name[i]))
            else:
                print("{}-{}-{}\t{}:{}:{}\t".format(fcb[Dir[path - 1].link[i]].year,fcb[Dir[path - 1].link[i]].month,fcb[Dir[path - 1].link[i]].day,fcb[Dir[path - 1].link[i]].hour,fcb[Dir[path - 1].link[i]].minute,fcb[Dir[path - 1].link[i]].second),end="")
                print("{}\t".format(fcb[Dir[path - 1].link[i]].length),end="")
                print("{}".format(Dir[path - 1].name[i]))
        Dir[path - 1].name[i]=Dir[path - 1].name[i][0:len(Dir[path - 1].name[i])-1]

def outputpath():
    print("C:\\>",end="")
    for i in range(step):
        print("{}>".format(steps[i]),end="")
    return True

pts=[0 for i in range(100)]
pt=0
all={}
pts[pt]="C:\\"
def filepath(p):                         #输出文件全路径,和内存的接口
    global Dir,fcb,pts,pt,all
    for i in range(2,Dir[p-1].num):
        way=""
        if not Dir[p-1].judge[i]:
            pt+=1
            pts[pt]=Dir[p-1].name[i]+"\\"
            filepath(Dir[p-1].link[i])
            pt-=1
        else:
            pt+=1
            pts[pt]=fcb[Dir[p-1].link[i]].name
            for j in range(pt+1):
                way+=pts[j]
            all[way]=fcb[Dir[p-1].link[i]].length
            pt-=1
    print(all)
    return all



def _Search(op,p):
    global Dir, fcb, pts1, pt1, all2
    for i in range(2, Dir[p - 1].num):
        way = ""
        if not Dir[p - 1].judge[i]:
            pt1 += 1
            pts1[pt1] = Dir[p - 1].name[i] + "\\"
            _Search(op,Dir[p - 1].link[i])
            pt1 -= 1
        else:
            pt1 += 1
            if op==fcb[Dir[p - 1].link[i]].name:
                pts1[pt1] = fcb[Dir[p - 1].link[i]].name
                for j in range(pt1 + 1):
                    way += pts1[j]
                result[way] = fcb[Dir[p - 1].link[i]].length
                pt1 -= 1

def choose():
    while outputpath():
        op=input()
        if op=="exit":
            break
        if op=='cd':
            opname=input()
            cd(opname)
        elif op=="rd":
            opname = input()
            rd(opname);
        elif op=="md":
            opname = input()
            md(opname)
        elif op=="tree":
            tree(path,0)
        elif op=="mk":
            opname = input()
            leng=eval(input())
            mk(opname,leng)
        elif op=="rk":
            opname=input()
            rk(opname)
        elif op=="fp":
            filepath(1)
        elif op=="dir":
            choose=input()
            if choose!="":
                _dir(choose)
            else:
                dir()
def _mk(path, size):
    global Dir
    pl = path.split("\\")
    print(pl)
    m = 0
    for i in range(1, len(pl) - 1):
        count = 0
        for j in range(Dir[i - 1].num):
            if Dir[i - 1].name[j] == pl[i]:
                count = 1
        if count == 0:
            md(pl[i])
        cd(pl[i])
        m = i
    if size == 0:
        md(pl[m + 1])
    else:
        mk(pl[m + 1], size)
    for i in range(1, len(pl)):
        cd('..')
def main():
    t=init(0,1)
    i=init_bit_map()
    sc=SC()
    #k=_mk('C:\\Dig\\xjx',10)
    # # k2 = _mk('C:\\Dig\\lql\\dpp', 10)
    p=sc.pac()
    s=sc.exhibit()
    to=sc.tojson(s)
    print(to)

    # k1=_mk('C:\\test',10)
    # p=pac()
    # s=exhibit(p)
    # to=tojson(s)
    # print(p)
    # #s=_Search("plat",1)
    # c=choose()
main()
